#pragma once

#include "CLog.h"

#include <sstream>
#include <string>
#include <fstream>
#include <iostream>
#include <cstdarg>

#include <windows.h>

using namespace PRO;

string_t CLog::time()
{
	static uint32_t start_time(GetTickCount());
	std::ostringstream oss;

	oss	<< "+ ";
	oss.width(6);
	oss << GetTickCount() - start_time;
	start_time = GetTickCount();
	oss	<< ":\t";

	return oss.str();
}

CLog& CLog::instance()
{
	static CLog log;
	return log;
}

CLog::CLog() :
log_file_("PROEngine.log", std::ios::app)
{
	opened_ = !log_file_.fail();
}

CLog::~CLog()
{
	std::cout << "++++++++++++[ END LOG ]++++++++++++" << std::endl << std::endl;
	log_file_.flush();
	log_file_ << std::endl << std::endl << "++++++++++++[ END LOG ]++++++++++++" << std::endl << std::endl;
	log_file_.close();
}

void CLog::begin()
{
	if (!opened_) return;

	std::cout << "++++++++++++[ BEGIN LOG ]++++++++++++" << std::endl;
	log_file_ << "++++++++++++[ BEGIN LOG ]++++++++++++" << std::endl;
}

void CLog::clear()
{
	if (opened_) log_file_.close();
	log_file_.open("PROEngine.log", std::ios::out);
	opened_ = !log_file_.fail();
}

CLog& CLog::endl()
{
	std::cout << std::endl;
	CLog::instance().log_file_ << std::endl;
	return CLog::instance();
}

CLog& CLog::operator<<(const char& data)
{
	std::cout << data;
	log_file_ << data;
	return *this;
}

CLog& CLog::operator<<(const short& data)
{
	std::cout << data;
	log_file_ << data;
	return *this;
}

CLog& CLog::operator<<(const long& data)
{
	std::cout << data;
	log_file_ << data;
	return *this;
}

CLog& CLog::operator<<(const unsigned char& data)
{
	std::cout << data;
	log_file_ << data;
	return *this;
}

CLog& CLog::operator<<(const unsigned short& data)
{
	std::cout << data;
	log_file_ << data;
	return *this;
}

CLog& CLog::operator<<(const unsigned long& data)
{
	std::cout << data;
	log_file_ << data;
	return *this;
}

CLog& CLog::operator<<(const float & data)
{
	std::cout << data;
	log_file_ << data;
	return *this;
}

CLog& CLog::operator<<(const std::string& data)
{
	std::cout << data;
	log_file_ << data;
	return *this;
}

CLog& CLog::operator<<(const CLog& data)
{
	return *this;
}